use std::process::{Command, Stdio, Child};
use std::fs::OpenOptions;
use std::io::{Write, BufRead, BufReader};
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use serde::{Deserialize, Serialize};
use std::os::windows::process::CommandExt;
use windows_sys::Win32::System::Console::{ATTACH_PARENT_PROCESS, AttachConsole};
use windows_sys::Win32::System::Console::{GenerateConsoleCtrlEvent, CTRL_C_EVENT};

// Windows API 常量
const CREATE_NO_WINDOW: u32 = 0x08000000;
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScumProcessInfo {
    pub pid: u32,
    pub start_time: String,
    pub log_file: String,
}

pub struct ScumControl {
    process: Arc<Mutex<Option<Child>>>,
    process_info: Arc<Mutex<Option<ScumProcessInfo>>>,
    log_buffer: Arc<Mutex<Vec<String>>>,
    window: Option<tauri::Window>,
}

impl ScumControl {
    pub fn new() -> Self {
        Self {
            process: Arc::new(Mutex::new(None)),
            process_info: Arc::new(Mutex::new(None)),
            log_buffer: Arc::new(Mutex::new(Vec::new())),
            window: None,
        }
    }

    pub fn set_window(&mut self, window: tauri::Window) {
        self.window = Some(window);
    }

    pub fn get_window(&self) -> Option<&tauri::Window> {
        self.window.as_ref()
    }

    pub fn start_server(&mut self, exe_path: &str) -> Result<(), String> {
        // 检查可执行文件是否存在
        if !Path::new(exe_path).exists() {
            return Err(format!("SCUM服务器可执行文件不存在: {}", exe_path));
        }

        // 检查是否已经在运行
        if self.is_running() {
            return Err("SCUM服务器已经在运行".to_string());
        }

        // 创建日志文件路径
        let log_dir = self.get_log_directory();
        std::fs::create_dir_all(&log_dir)
            .map_err(|e| format!("创建日志目录失败: {}", e))?;

        // 使用固定的日志文件名
        let log_file = format!("{}/scum_server.log", log_dir);
        
        // 清空日志文件内容（如果文件存在的话）
        if Path::new(&log_file).exists() {
            std::fs::write(&log_file, "")
                .map_err(|e| format!("清空日志文件失败: {}", e))?;
            println!("已清空日志文件: {}", log_file);
        }

        // 启动服务器进程
        let mut command = Command::new(exe_path);
        command
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .current_dir(Path::new(exe_path).parent().unwrap_or(Path::new(".")))
             .creation_flags(CREATE_NEW_PROCESS_GROUP);

        let child = command.spawn()
            .map_err(|e| format!("启动SCUM服务器失败: {}", e))?;

        let pid = child.id();
        let start_time = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

        // 保存进程信息
        let process_info = ScumProcessInfo {
            pid,
            start_time: start_time.clone(),
            log_file: log_file.clone(),
        };

        // 克隆process_info用于保存
        let process_info_clone = process_info.clone();

        // 更新状态 - 先保存进程引用
        {
            let mut process_guard = self.process.lock().unwrap();
            *process_guard = Some(child);
        }

        {
            let mut info_guard = self.process_info.lock().unwrap();
            *info_guard = Some(process_info);
        }

        // 启动日志监控线程 - 从process中获取child
        {
            let mut process_guard = self.process.lock().unwrap();
            if let Some(child) = process_guard.take() {
                let child = self.start_log_monitoring(child, log_file.clone());
                // 重新放回process
                *process_guard = Some(child);
            }
        }

        // 保存进程ID到配置
        self.save_process_info(&process_info_clone)?;

        Ok(())
    }

    pub fn stop_server(&mut self) -> Result<bool, String> {
        if !self.is_running() {
            return Err("SCUM服务器未在运行".to_string());
        }

        // 获取进程信息
        let process_info = {
            let info_guard = self.process_info.lock().unwrap();
            info_guard.clone()
        };

        if let Some(info) = process_info {
            // 直接使用taskkill命令强制终止，减少等待时间
            unsafe {
                if AttachConsole(ATTACH_PARENT_PROCESS) == 0 {
                    return Err("附加控制台失败".to_string());
                }
        
                if GenerateConsoleCtrlEvent(CTRL_C_EVENT, info.pid) == 0 {
                    return Err("发送 Ctrl+C 失败".to_string());
                }
            }
        }

        

        self.cleanup_after_stop()?;
        Ok(false) // 不需要等待
    }

    fn cleanup_after_stop(&mut self) -> Result<(), String> {
        // 清除进程信息
        {
            let mut info_guard = self.process_info.lock().unwrap();
            *info_guard = None;
        }

        // 清除配置中的进程信息
        self.clear_process_info()?;

        Ok(())
    }

    pub fn is_running(&self) -> bool {
        // 首先检查process字段
        let mut process_guard = self.process.lock().unwrap();
        if let Some(ref mut child) = *process_guard {
            // 检查进程是否还在运行
            match child.try_wait() {
                Ok(Some(_)) => {
                    false
                }
                Ok(None) => {
                    true
                }
                Err(_) => {
                    false
                }
            }
        } else {
            // 如果process字段为None，检查是否有已恢复的进程信息
            let info_guard = self.process_info.lock().unwrap();
            if let Some(ref info) = *info_guard {
                // 检查进程是否还在运行
                let result = self.is_process_running(info.pid);
                result
            } else {
                false
            }
        }
    }

    #[allow(dead_code)]
    pub fn get_process_info(&self) -> Option<ScumProcessInfo> {
        let info_guard = self.process_info.lock().unwrap();
        info_guard.clone()
    }

    pub fn get_logs(&self, lines: usize) -> Vec<String> {
        // 首先尝试从内存缓冲区获取
        let buffer_guard = self.log_buffer.lock().unwrap();
        if !buffer_guard.is_empty() {
            let total_lines = buffer_guard.len();
            let start = if total_lines > lines {
                total_lines - lines
            } else {
                0
            };
            return buffer_guard[start..].to_vec();
        }
        
        // 如果内存缓冲区为空，尝试从日志文件读取
        let log_dir = self.get_log_directory();
        let log_file = format!("{}/scum_server.log", log_dir);
        
        if let Ok(content) = std::fs::read_to_string(&log_file) {
            let lines_vec: Vec<String> = content.lines().map(|s| s.to_string()).collect();
            let total_lines = lines_vec.len();
            let start = if total_lines > lines {
                total_lines - lines
            } else {
                0
            };
            lines_vec[start..].to_vec()
        } else {
            vec!["暂无日志".to_string()]
        }
    }

    fn start_log_monitoring(&self, mut child: Child, log_file: String) -> Child {
        let stdout = child.stdout.take().expect("无法获取stdout");
        let stderr = child.stderr.take().expect("无法获取stderr");
        let log_buffer = Arc::clone(&self.log_buffer);
        let window = self.window.clone();

        // 创建日志文件
        let log_file_handle = OpenOptions::new()
            .create(true)
            .append(true)
            .open(&log_file)
            .expect("无法创建日志文件");

        // 监控stdout
        let log_buffer_stdout = Arc::clone(&log_buffer);
        let mut log_file_handle_stdout = log_file_handle.try_clone().unwrap();
        let window_stdout = window.clone();
        
        thread::spawn(move || {
            let reader = BufReader::new(stdout);
            for line in reader.lines() {
                if let Ok(line_content) = line {
                    let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
                    let log_entry = format!("[{}] {}", timestamp, line_content);
                    
                    // 写入文件
                    let _ = writeln!(log_file_handle_stdout, "{}", log_entry);
                    
                    // 添加到内存缓冲区
                    {
                        let mut buffer = log_buffer_stdout.lock().unwrap();
                        buffer.push(log_entry.clone());
                        // 限制缓冲区大小
                        if buffer.len() > 1000 {
                            buffer.remove(0);
                        }
                    }
                    
                    // 推送到前端
                    if let Some(window) = &window_stdout {
                        let _ = window.emit("scum_log_update", log_entry);
                    }
                }
            }
        });

        // 监控stderr
        let log_buffer_stderr = Arc::clone(&log_buffer);
        let mut log_file_handle_stderr = log_file_handle.try_clone().unwrap();
        let window_stderr = window.clone();
        
        thread::spawn(move || {
            let reader = BufReader::new(stderr);
            for line in reader.lines() {
                if let Ok(line_content) = line {
                    let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
                    let log_entry = format!("[{}] [ERROR] {}", timestamp, line_content);
                    
                    // 写入文件
                    let _ = writeln!(log_file_handle_stderr, "{}", log_entry);
                    
                    // 添加到内存缓冲区
                    {
                        let mut buffer = log_buffer_stderr.lock().unwrap();
                        buffer.push(log_entry.clone());
                        // 限制缓冲区大小
                        if buffer.len() > 1000 {
                            buffer.remove(0);
                        }
                    }
                    
                    // 推送到前端
                    if let Some(window) = &window_stderr {
                        let _ = window.emit("scum_log_update", log_entry);
                    }
                }
            }
        });

        // 监控进程状态 - 使用进程ID而不是Child对象
        let window_status = window.clone();
        let pid = child.id();
        thread::spawn(move || {
            // 使用进程ID来监控状态，而不是直接使用Child对象
            loop {
                thread::sleep(Duration::from_secs(1));
                // 检查进程是否还在运行
                let output = Command::new("tasklist")
                    .args(&["/FI", &format!("PID eq {}", pid), "/FO", "CSV"])
                    .creation_flags(CREATE_NO_WINDOW)
                    .output();
                
                match output {
                    Ok(output) => {
                        let output_str = String::from_utf8_lossy(&output.stdout);
                        if !output_str.contains(&pid.to_string()) {
                            // 进程已结束
                            if let Some(window) = &window_status {
                                let _ = window.emit("scum_status_changed", "stopped");
                            }
                            break;
                        }
                    }
                    Err(_) => {
                        // 出错，认为进程已结束
                        if let Some(window) = &window_status {
                            let _ = window.emit("scum_status_changed", "stopped");
                        }
                        break;
                    }
                }
            }
        });

        child
    }

    fn get_log_directory(&self) -> String {
        let config_dir = dirs::document_dir()
            .unwrap_or_else(|| std::path::PathBuf::from("."))
            .join("Ac-God-Panel")
            .join("logs");
        config_dir.to_string_lossy().to_string()
    }

    fn save_process_info(&self, info: &ScumProcessInfo) -> Result<(), String> {
        let config = crate::config::AppConfig::load()?;
        let mut settings = config.settings.clone();
        settings.insert("scum_process_pid".to_string(), info.pid.to_string());
        settings.insert("scum_process_start_time".to_string(), info.start_time.clone());
        settings.insert("scum_log_file".to_string(), info.log_file.clone());
        
        let mut new_config = config;
        new_config.settings = settings;
        new_config.save()
    }

    fn clear_process_info(&self) -> Result<(), String> {
        let config = crate::config::AppConfig::load()?;
        let mut settings = config.settings.clone();
        settings.remove("scum_process_pid");
        settings.remove("scum_process_start_time");
        settings.remove("scum_log_file");
        
        let mut new_config = config;
        new_config.settings = settings;
        new_config.save()
    }

    pub fn load_process_info(&self) -> Result<Option<ScumProcessInfo>, String> {
        let config = crate::config::AppConfig::load()?;
        
        if let (Some(pid_str), Some(start_time), Some(log_file)) = (
            config.settings.get("scum_process_pid"),
            config.settings.get("scum_process_start_time"),
            config.settings.get("scum_log_file")
        ) {
            if let Ok(pid) = pid_str.parse::<u32>() {
                return Ok(Some(ScumProcessInfo {
                    pid,
                    start_time: start_time.clone(),
                    log_file: log_file.clone(),
                }));
            }
        }
        
        Ok(None)
    }

    fn kill_process_with_taskkill(&self, pid: u32) -> Result<(), String> {
        let output = Command::new("taskkill")
            .args(&["/f", "/pid", &pid.to_string()])
            .creation_flags(0x08000000) // CREATE_NO_WINDOW
            .output()
            .map_err(|e| format!("taskkill命令执行失败: {}", e))?;

        if output.status.success() {
            Ok(())
        } else {
            let error_msg = String::from_utf8_lossy(&output.stderr);
            Err(format!("taskkill命令失败: {}", error_msg))
        }
    }

    fn terminate_process_with_api(&self, pid: u32) -> Result<(), String> {
        use std::ffi::c_void;
        
        // 定义Windows API函数
        #[link(name = "kernel32")]
        extern "system" {
            fn OpenProcess(dwDesiredAccess: u32, bInheritHandle: i32, dwProcessId: u32) -> *mut c_void;
            fn TerminateProcess(hProcess: *mut c_void, uExitCode: u32) -> i32;
            fn CloseHandle(hObject: *mut c_void) -> i32;
        }
        
        const PROCESS_TERMINATE: u32 = 0x0001;
        
        unsafe {
            // 打开进程句柄
            let handle = OpenProcess(PROCESS_TERMINATE, 0, pid);
            if handle.is_null() {
                return Err("无法打开进程句柄".to_string());
            }
            
            // 强制终止进程
            let result = TerminateProcess(handle, 1);
            CloseHandle(handle);
            
            if result == 0 {
                return Err("TerminateProcess失败".to_string());
            }
            
            Ok(())
        }
    }

    fn is_process_running(&self, pid: u32) -> bool {
        let output = Command::new("tasklist")
            .args(&["/FI", &format!("PID eq {}", pid), "/FO", "CSV"])
            .creation_flags(CREATE_NO_WINDOW)
            .output();
        
        match output {
            Ok(output) => {
                let output_str = String::from_utf8_lossy(&output.stdout);
                output_str.contains(&pid.to_string())
            }
            Err(_) => false
        }
    }

    // 新增：恢复进程状态
    pub fn restore_process_state(&mut self) -> Result<(), String> {
        println!("开始恢复进程状态...");
        
        // 从配置中加载进程信息
        if let Ok(Some(process_info)) = self.load_process_info() {
            println!("从配置中加载到进程信息: PID={}", process_info.pid);
            
            // 检查进程是否还在运行
            if self.is_process_running(process_info.pid) {
                println!("发现SCUM服务器进程仍在运行，PID: {}", process_info.pid);
                
                // 更新进程信息
                {
                    let mut info_guard = self.process_info.lock().unwrap();
                    *info_guard = Some(process_info.clone());
                }
                
                // 更新配置状态
                let mut config = crate::config::AppConfig::load()?;
                config.set_scum_server_running(true)?;
                
                // 启动日志监控（但不重新启动进程）
                self.start_log_monitoring_for_existing_process(process_info.pid, process_info.log_file.clone());
                
                // 发送状态变化事件到前端
                if let Some(window) = &self.window {
                    println!("发送状态变化事件: running");
                    let _ = window.emit("scum_status_changed", "running");
                } else {
                    println!("警告: window为None，无法发送事件");
                }
                
                println!("已恢复SCUM服务器状态");
            } else {
                println!("配置中的进程已不存在，清理状态");
                // 进程不存在，清理状态
                self.cleanup_after_stop()?;
                
                // 发送状态变化事件到前端
                if let Some(window) = &self.window {
                    println!("发送状态变化事件: stopped");
                    let _ = window.emit("scum_status_changed", "stopped");
                } else {
                    println!("警告: window为None，无法发送事件");
                }
            }
        } else {
            println!("配置中没有进程信息");
        }
        
        Ok(())
    }

    // 新增：为已存在的进程启动日志监控
    fn start_log_monitoring_for_existing_process(&self, pid: u32, log_file: String) {
        let window = self.window.clone();
        
        // 启动日志文件监控线程
        let window_log = window.clone();
        thread::spawn(move || {
            Self::monitor_log_file(log_file, window_log);
        });
        
        // 启动进程状态监控线程
        let window_status = window.clone();
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_secs(1));
                // 检查进程是否还在运行
                let output = Command::new("tasklist")
                    .args(&["/FI", &format!("PID eq {}", pid), "/FO", "CSV"])
                    .creation_flags(CREATE_NO_WINDOW)
                    .output();
                
                match output {
                    Ok(output) => {
                        let output_str = String::from_utf8_lossy(&output.stdout);
                        if !output_str.contains(&pid.to_string()) {
                            // 进程已结束
                            if let Some(window) = &window_status {
                                let _ = window.emit("scum_status_changed", "stopped");
                            }
                            break;
                        }
                    }
                    Err(_) => {
                        // 出错，认为进程已结束
                        if let Some(window) = &window_status {
                            let _ = window.emit("scum_status_changed", "stopped");
                        }
                        break;
                    }
                }
            }
        });
    }

    // 新增：监控日志文件
    fn monitor_log_file(log_file: String, window: Option<tauri::Window>) {
        use std::fs::File;
        use std::io::{Seek, SeekFrom};
        
        let mut last_size = 0u64;
        
        loop {
            thread::sleep(Duration::from_millis(500));
            
            if let Ok(file) = File::open(&log_file) {
                if let Ok(metadata) = file.metadata() {
                    let current_size = metadata.len();
                    
                    if current_size > last_size {
                        // 文件有新内容，读取新增部分
                        if let Ok(mut file) = File::open(&log_file) {
                            if let Ok(_) = file.seek(SeekFrom::Start(last_size)) {
                                let reader = BufReader::new(file);
                                for line in reader.lines() {
                                    if let Ok(line_content) = line {
                                        let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
                                        let log_entry = format!("[{}] {}", timestamp, line_content);
                                        
                                        // 推送到前端
                                        if let Some(window) = &window {
                                            let _ = window.emit("scum_log_update", log_entry);
                                        }
                                    }
                                }
                            }
                        }
                        last_size = current_size;
                    }
                }
            } else {
                // 文件不存在，等待一段时间再试
                thread::sleep(Duration::from_secs(1));
            }
        }
    }
} 